home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
The World of Computer Software.iso
/
tosspd.zip
/
TOSS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-12-16
|
35KB
|
1,364 lines
#include"msg.h"
WIN title={NULL,0,0,50,2,0x38,0x0,0x70,0,0," TOSS 1.2 (Beta) QWK->RBBS->REP Message Tosser Copyright 1992 Jim Storch"};
WIN stat={NULL,1,2,49,12,0x19,0x1b,0x1f,0,0,"STATUS"};
WIN warn={NULL,1,15,49,21,0x4c,0x4b,0x4f,0,0,"WARNINGS"};
WIN proc={NULL,52,2,77,21,0x2a,0x20,0x2f,0,0,"PROCESSING"};
CONFIG config={
FALSE,
FALSE,
FALSE,
"",
"",
"Brought to you by ELHARB (703)730-0542 Woodbridge,VA",
"",
"",
"PKZIP -ex",
"PKUNZIP -o",
"",
"",
NULL,NULL,NULL,NULL,NULL,
0,0,0,0};
int main(int argc, char *argv[])
{
clrscr();
wallpaper(&title);
openwin(&stat);
openwin(&warn);
openwin(&proc);
if(argc<2) failure("Missing Command Line Arguments-\n"
"USAGE: TOSS [export/import] HOST.CFG\n");
if(strcmpi(argv[1],"EXPORT")==0)
export(argv[2]);
else
if(strcmpi(argv[1],"IMPORT")==0)
import(argv[2]);
else
failure("Improper Command Line Arguments-\n"
"USAGE: TOSS [export/import] HOST.CFG\n");
gotoxy(1,24);
return(0);
}
/********************************************************
Test to make sure the specified work directory is valid.
If bad, try to create.
********************************************************/
void checkworkdir(char *dir)
{
if(access(dir,0))
{
printfwin(&stat,"Creating work directory:\n %s\n",dir);
if (mkdir(dir)!=0)
failure("Cannot create work directory:\n %s\n",dir);
}
}
/**************************
Uncompress the .QWK packet
**************************/
void unzip(void)
{
char comline[256];
int *tbuff,x,zipstat;
int far *screen;
struct text_info tinfo;
gettextinfo(&tinfo);
if(tinfo.currmode==MONO)
screen=(int far *)0xB0000000;
else
screen=(int far *)0xB8000000;
tbuff=e_malloc(4000*sizeof(char));
strcpy(comline,config.unzip);
strcat(comline," ");
strcat(comline,config.qwkname);
strcat(comline," ");
strcat(comline,config.workdir);
printfwin(&stat,"->Uncompressing:\n%s\n",comline);
for(x=0;x<2000;x++)
*(tbuff+x)= *(screen+x);
clrscr();
system(comline);
for(x=0;x<2000;x++)
*(screen+x)= *(tbuff+x);
free(tbuff);
}
/************************
Compress the .REP packet
************************/
void zip(void)
{
char comline[256];
int *tbuff,x;
int far *screen;
struct text_info tinfo;
gettextinfo(&tinfo);
if(tinfo.currmode==MONO)
screen=(int far *)0xB0000000;
else
screen=(int far *)0xB8000000;
tbuff=e_malloc(4000*sizeof(char));
strcpy(comline,config.zip);
strcat(comline," ");
strcat(comline,config.repname);
strcat(comline," ");
strcat(comline,config.workdir);
strcat(comline,"\\");
strcat(comline,config.hostname);
strcat(comline,".MSG" );
printfwin(&stat,"->Compressing:\n%s\n",comline);
for(x=0;x<2000;x++)
*(tbuff+x)= *(screen+x);
clrscr();
system(comline);
for(x=0;x<2000;x++)
*(screen+x)= *(tbuff+x);
free(tbuff);
}
/*********************************
Export from the RBBS message file
to a .REP packet for the host
*********************************/
void export(char *host)
{
char twirl[]="\\\\||||////----";
int s=0;
struct ll_conf *conf;
struct ll_swap *swap;
MSG *msg;
FILE *infile, *outfile;
int count=0;
char rep[81],to,from;
char buff[128];
read_config(&config,host);
msg=(MSG *)e_malloc(sizeof(MSG));
strcpy(rep,config.workdir);
strcat(rep,"\\");
strcat(rep,config.hostname);
strcat(rep,".MSG");
if(access(config.repname,0)==0 && access(rep,0)==0 && config.append==TRUE)
{
printfwin(&stat,"->Appending: \"%s\"\n",rep);
if ((outfile=fopen(rep,"ab"))==NULL)
failure("Cannot append reply file:\n\"%s\"\n",rep);
}
else
{
printfwin(&stat,"->Creating: \"%s\"\n",rep);
if ((outfile=fopen(rep,"wb"))==NULL)
failure("Cannot make reply file:\n\"%s\"\n",rep);
padcpy(buff,config.hostname,128);
addblock(buff,outfile);
}
conf=config.conf;
while(conf!=NULL)
{
printfwin(&stat,"->Reading: \"%s\"\n",conf->path);
if ((infile=fopen(conf->path,"rb"))==NULL)
failure("Cannot open RBBS msg file:\n\"%s\"\n",conf->path);
pos_rbbs(infile);
while(read_rbbs(msg,infile)!=-1)
{
if(msg->number <= conf->last_read || !msg->active)
{
printfwin(&proc,"%c\b",twirl[s]);
s++;
if(s>14) s=0;
free(msg->text_buffer);
continue;
}
if(msg->priv && !config.pass_private && !exempt(msg))
{
show_header(msg);
printfwin(&proc,"** Private mail skipped **\n",msg->number);
free(msg->text_buffer);
continue;
}
if(deny(msg) && !exempt(msg))
{
show_header(msg);
printfwin(&proc,"** Denied EXPORT rights **\n");
free(msg->text_buffer);
continue;
}
swap=config.export;
to=from=FALSE;
while(swap!=NULL)
{
if(strncmp(msg->from,swap->from,22)==0 && from==FALSE)
{
termcpy(msg->from,swap->to,31);
from=TRUE;
}
if(strncmp(msg->to,swap->from,22)==0 && to==FALSE)
{
termcpy(msg->to,swap->to,25);
to=TRUE;
}
swap=swap->next;
}
show_header(msg);
conf->processed++;
count++;
conf->last_read=msg->number;
addtag(msg);
msg->number=conf->number;
msg->conf=conf->number;
write_qwk(msg,outfile);
free(msg->text_buffer);
}
printfwin(&stat," %d messages processed\n",conf->processed);
fclose(infile);
conf=conf->next;
}
free(msg);
make_lmr();
fclose(outfile);
printfwin(&stat," %d Total Messages Processed\n",count);
if(count!=0)
zip();
//printfwin(&proc," ");
printfwin(&stat,"->ALL DONE! Thank you for using TOSS.\n");
}
/*********************************
Import to the RBBS message file
from a .QWK packet from the host
*********************************/
void import(char *host)
{
struct ll_conf *conf;
struct ll_swap *swap;
MSG *msg;
FILE *infile;
char dat[128],to,from;
int mcount=0;
int lastconf=0;
read_config(&config,host);
unzip();
msg=(MSG *)e_malloc(sizeof(MSG));
strcpy(dat,config.workdir);
strcat(dat,"\\");
strcat(dat,"MESSAGES.DAT");
printfwin(&stat,"->Reading: \"%s\"\n",dat);
if ((infile=fopen(dat,"rb"))==NULL)
failure("Cannot open message file:\n\"%s\"\n",dat);
pos_qwk(infile);
while(read_qwk(msg,infile)!=-1)
{
if(msg->priv && !config.pass_private && !exempt(msg))
{
show_header(msg);
printfwin(&proc,"** Private mail skipped **\n");
free(msg->text_buffer);
continue;
}
if(deny(msg) && !exempt(msg))
{
show_header(msg);
printfwin(&proc,"** Denied IMPORT rights! **\n");
free(msg->text_buffer);
continue;
}
swap=config.import;
to=from=FALSE;
while(swap!=NULL)
{
if(strncmp(msg->from,swap->from,22)==0 && from==FALSE)
{
termcpy(msg->from,swap->to,31);
from=TRUE;
}
if(strncmp(msg->to,swap->from,22)==0 && to==FALSE)
{
termcpy(msg->to,swap->to,25);
to=TRUE;
}
swap=swap->next;
}
conf=config.conf;
while(conf!=NULL)
{
if(msg->conf==conf->number)
{
if(lastconf!=msg->conf)
{
printfwin(&stat,"->Writing: \"%s\"\n",conf->path);
lastconf=msg->conf;
}
conf->last_read=write_rbbs(msg,conf->path);
show_header(msg);
mcount++;
break;
}
conf=conf->next;
}
free(msg->text_buffer);
}
printfwin(&stat," %d messages processed\n",mcount);
fclose(infile);
free(msg);
make_lmr();
remove(dat);
if(config.killqwk==TRUE)
{
printfwin(&stat,"->Deleting: \"%s\"\n",config.qwkname);
remove(config.qwkname);
}
printfwin(&stat,"->ALL DONE! Thank you for using TOSS.\n");
}
/****************************************************
Return TRUE if message is to/from a user denied mail
****************************************************/
int deny(MSG *msg)
{
struct ll_who *who;
who=config.loser;
while(who!=NULL)
{
if(strncmpi(who->user,msg->from,22)==0)
return(TRUE);
if(strncmpi(who->user,msg->to,22)==0)
return(TRUE);
who=who->next;
}
return(FALSE);
}
/****************************************
Return TRUE if message is to/from a user
exempt from the private mail filter
****************************************/
int exempt(MSG *msg)
{
struct ll_who *who;
who=config.exempt;
while(who!=NULL)
{
if(strncmpi(who->user,msg->from,22)==0)
return(TRUE);
if(strncmpi(who->user,msg->to,22)==0)
return(TRUE);
who=who->next;
}
return(FALSE);
}
/*************************************************
Read in the configuration file and convert to the
info held in CONFIG.
*************************************************/
void read_config(CONFIG *config,char *cfgfile)
{
FILE *infile;
struct ll_who *who,**w_ptr;
struct ll_swap *swap,**s_ptr;
struct ll_conf *conf,**c_ptr;
struct LMR lmr;
int count=0;
char line[100];
printfwin(&stat,"->Reading: \"%s\"\n",cfgfile);
if ((infile=fopen(cfgfile,"rt"))==NULL)
failure("Cannot open host configuration file:\n\"%s\"\n",cfgfile);
while(instr(line,infile)!=-1)
{
count++;
remls(line);
if(strlen(line)<5)
continue;
if(*line==';')
continue;
if(strncmpi(line,"TAGL",4)==0)
{
strtok(line,"=");
strncpy(config->tagline,strtok(NULL,"\0"),70);
continue;
}
strupr(line);
if(strncmpi(line,"CONF",4)==0)
{
conf=(struct ll_conf *)malloc(sizeof(struct ll_conf));
strtok(line,"=");
conf->number=atoi(strtok(NULL,","));
strncpy(conf->path,strtok(NULL,"\0"),80);
conf->next=NULL;
conf->processed=0;
conf->last_read=0;
c_ptr=&config->conf;
while(*c_ptr!=NULL)
c_ptr=&(*c_ptr)->next;
*c_ptr=conf;
config->conf_count++;
continue;
}
if(strncmpi(line,"IMPO",4)==0)
{
swap=(struct ll_swap *)malloc(sizeof(struct ll_swap));
strtok(line,"=");
padzcpy(swap->from,strtok(NULL,","),32);
padzcpy(swap->to,strtok(NULL,"\0"),32);
swap->next=NULL;
s_ptr=&config->import;
while(*s_ptr!=NULL)
s_ptr=&(*s_ptr)->next;
*s_ptr=swap;
continue;
}
if(strncmpi(line,"EXPO",4)==0)
{
swap=(struct ll_swap *)malloc(sizeof(struct ll_swap));
strtok(line,"=");
padzcpy(swap->from,strtok(NULL,","),32);
padzcpy(swap->to,strtok(NULL,"\0"),32);
swap->next=NULL;
s_ptr=&config->export;
while(*s_ptr!=NULL)
s_ptr=&(*s_ptr)->next;
*s_ptr=swap;
continue;
}
if(strncmpi(line,"EXEM",4)==0)
{
who=(struct ll_who *)malloc(sizeof(struct ll_who));
strtok(line,"=");
padzcpy(who->user,strtok(NULL,"\0"),32);
who->next=NULL;
w_ptr=&config->exempt;
while(*w_ptr!=NULL)
w_ptr=&(*w_ptr)->next;
*w_ptr=who;
continue;
}
if(strncmpi(line,"DENY",4)==0)
{
who=(struct ll_who *)malloc(sizeof(struct ll_who));
strtok(line,"=");
padzcpy(who->user,strtok(NULL,"\0"),32);
who->next=NULL;
w_ptr=&config->loser;
while(*w_ptr!=NULL)
w_ptr=&(*w_ptr)->next;
*w_ptr=who;
continue;
}
if(strncmpi(line,"WORK",4)==0)
{
strtok(line,"=");
strncpy(config->workdir,strtok(NULL,"\0"),80);
if(*(config->workdir+strlen(config->workdir)-1)=='\\')
*(config->workdir+strlen(config->workdir)-1)='\0';
continue;
}
if(strncmpi(line,"QWKN",4)==0)
{
strtok(line,"=");
strncpy(config->qwkname,strtok(NULL,"\0"),80);
continue;
}
if(strncmpi(line,"REPN",4)==0)
{
strtok(line,"=");
strncpy(config->repname,strtok(NULL,"\0"),80);
continue;
}
if(strncmpi(line,"LOGF",4)==0)
{
strtok(line,"=");
strncpy(config->logfile,strtok(NULL,"\0"),80);
continue;
}
if(strncmpi(line,"HOST",4)==0)
{
strtok(line,"=");
strncpy(config->hostname,strtok(NULL,"\0"),9);
strcpy(config->lmrname,config->hostname);
strcat(config->lmrname,".LMR");
continue;
}
if(strncmpi(line,"COMP",4)==0)
{
strtok(line,"=");
strncpy(config->zip,strtok(NULL,"\0"),80);
continue;
}
if(strncmpi(line,"UNCO",4)==0)
{
strtok(line,"=");
strncpy(config->unzip,strtok(NULL,"\0"),80);
continue;
}
if(strncmpi(line,"ALLO",4)==0)
{
strtok(line,"=");
padzcpy(line,strtok(NULL,"\0"),4);
if(strncmpi(line,"YES",3)==0)
config->pass_private=TRUE;
else
config->pass_private=FALSE;
continue;
}
if(strncmpi(line,"APPE",4)==0)
{
strtok(line,"=");
padzcpy(line,strtok(NULL,"\0"),4);
if(strncmpi(line,"YES",3)==0)
config->append=TRUE;
else
config->append=FALSE;
continue;
}
if(strncmpi(line,"KILLQ",4)==0)
{
strtok(line,"=");
padzcpy(line,strtok(NULL,"\0"),4);
if(strncmpi(line,"YES",3)==0)
config->killqwk=TRUE;
else
config->killqwk=FALSE;
continue;
}
printfwin(&warn,"--UNRECOGNIZED COMMAND--\n");
printfwin(&warn,"Line number %d of config file: \"%s\"\n",count,cfgfile);
printfwin(&warn,"\"%s\"\n",line);
}
fclose(infile);
if(strlen(config->repname)==0)
failure("'REPNAME=' not in config file:\n \"%s\"\n",cfgfile);
if(strlen(config->qwkname)==0)
failure("'QWKNAME=' not in config file:\n \"%s\"\n",cfgfile);
if(strlen(config->hostname)==0)
failure("'HOSTNAME=' not in config file:\n \"%s\"\n",cfgfile);
if(strlen(config->workdir)==0)
failure("'WORKDIR=' not in config file:\n \"%s\"\n",cfgfile);
if(config->conf==NULL)
failure("No 'CONF=' specified in config file:\n \"%s\"\n",cfgfile);
if(config->export==NULL)
{
printfwin(&warn,"--WARNING--\n");
printfwin(&warn,"No 'EXPORT=' conversions in config file:\n \"%s\"\n",cfgfile);
}
if(config->import==NULL)
{
printfwin(&warn,"--WARNING--\n");
printfwin(&warn,"No 'IMPORT=' conversions in config file:\n \"%s\"\n",cfgfile);
}
printfwin(&stat,"->Reading: \"%s\"\n",config->lmrname);
if(access(config->lmrname,0)!=0)
{
printfwin(&stat," Not found, starting from zero\n");
return;
}
if ((infile=fopen(config->lmrname,"rb"))==NULL)
failure("Error accessing .LRM file: \"%s\"\n",config->lmrname);
while(1)
{
fread(&lmr,sizeof(struct LMR),1,infile);
if(feof(infile))
break;
conf=config->conf;
while(conf!=NULL)
{
if(conf->number==lmr.number)
conf->last_read=lmr.last_read;
conf=conf->next;
}
}
fclose(infile);
checkworkdir(config->workdir);
}
/*************************************************
Make Last_Message_Read (.LMR) file for this host,
so we know where to start next time around
*************************************************/
void make_lmr(void)
{
struct ll_conf *conf;
struct LMR lmr;
FILE *outfile;
printfwin(&stat,"->Updating: \"%s\"\n",config.lmrname);
if ((outfile=fopen(config.lmrname,"wb"))==NULL)
failure("Error Creating .LRM file: \"%s\"\n",config.lmrname);
conf=config.conf;
while(conf!=NULL)
{
lmr.number=conf->number;
lmr.last_read=conf->last_read;
fwrite(&lmr,sizeof(struct LMR),1,outfile);
conf=conf->next;
}
fclose(outfile);
}
/****************************************************************************
QWK code starts here
****************************************************************************/
/****************************************
Set to the first message of a qwk packet
****************************************/
void pos_qwk(FILE *infile)
{
fseek(infile,128,SEEK_SET);
}
/***********************************************
Read in the next QWK message and convert to MSG
Returns -1 on End-Of-File
***********************************************/
int read_qwk(MSG *msg,FILE *infile)
{
struct QWK *qwk;
char temp[10];
long size;
int x;
qwk=(struct QWK *) e_malloc(sizeof(struct QWK));
fread(qwk,128,1,infile);
if(feof(infile))
return(-1);
// if Net-status block encountered, exit
if((qwk->active_flag!=225 && qwk->active_flag!=226) ||
qwk->date[2]!='-' ||
qwk->date[5]!='-')
return(-1);
msg->priv=FALSE;
if(qwk->active_flag==225)
msg->active=TRUE;
else
msg->active=FALSE;
termcpy(temp,qwk->msg_blk_size,6);
size=atol(temp);
msg->size=size;
termcpy(msg->from,qwk->from,25);
termcpy(msg->to,qwk->to,25);
termcpy(msg->subject,qwk->subject,22);
termcpy(msg->password,qwk->password,12);
msg->level=0;
msg->conf=qwk->conf_num;
termcpy(temp,qwk->number,4);
msg->number=atoi(temp);
msg->read.hour=32; // This is for RBBS:
msg->read.minute=32; // If set to all spaces,
msg->read.second=32; // RBBS assumes its unread.
msg->read.month=32;
msg->read.day=32;
msg->read.year=32;
strncpy(temp,qwk->time,5);
temp[2]='\0';
temp[5]='\0';
msg->sent.hour=atoi(temp);
msg->sent.minute=atoi(&temp[3]);
msg->sent.second=0;
strncpy(temp,qwk->date,8);
temp[2]='\0';
temp[5]='\0';
temp[8]='\0';
msg->sent.month=atoi(temp);
msg->sent.day=atoi(&temp[3]);
msg->sent.year=atoi(&temp[6]);
msg->text_buffer=(char *)e_malloc(size*128);
memset(msg->text_buffer,' ',size*128);
size--;
for(x=0;x<size;x++)
{
fread(msg->text_buffer+(128*x),128,1,infile);
if(feof(infile)) return(-1);
}
free(qwk);
return(size);
}
/*************************************
Write a message to a QWK message base
This will be a simple append.
*************************************/
void write_qwk(MSG *msg,FILE *outfile)
{
struct QWK *qwk;
char temp[33];
int textblocks,x;
qwk=(struct QWK *) e_malloc(sizeof(struct QWK));
if(msg->priv)
qwk->status_flag='+';
else
qwk->status_flag=' ';
padcpy(qwk->ref_msg_num,"",8);
qwk->network_flag=' ';
qwk->active_flag=225;
qwk->conf_num=msg->conf;
padcpy(qwk->number,ltoa(msg->number,temp,10),7);
padcpy(qwk->from,msg->from,25);
padcpy(qwk->to,msg->to,25);
padcpy(qwk->subject,msg->subject,25);
padcpy(qwk->password,"",12); // <- mod !#!#!#!
padcpy(qwk->msg_blk_size,ltoa(msg->size,temp,10),6);
sprintf(temp,"%d%d:%d%d\0",
msg->sent.hour/10,
msg->sent.hour%10,
msg->sent.minute/10,
msg->sent.minute%10);
strncpy(qwk->time,temp,5);
sprintf(temp,"%d%d-%d%d-%d%d\n",
msg->sent.month/10,
msg->sent.month%10,
msg->sent.day/10,
msg->sent.day%10,
msg->sent.year/10,
msg->sent.year%10);
strncpy(qwk->date,temp,8);
addblock(qwk,outfile);
textblocks=msg->size-1;
for(x=0;x<textblocks;x++)
addblock(msg->text_buffer+(128*x),outfile);
free(qwk);
}
/****************************************************************************
RBBS code starts here
****************************************************************************/
/**************************************************************
Set file pointer to the first message of an RBBS message base.
This value is recorded in the Check Point Record (first block)
**************************************************************/
void pos_rbbs(FILE *infile)
{
CPR *cpr;
cpr=(CPR*)e_malloc(sizeof(CPR));
read_rbbs_header(cpr,infile);
fseek(infile,128*cpr->first_msg_blk,SEEK_SET);
free(cpr);
}
/******************************************
Read in an RBBS message and convert to MSG
******************************************/
int read_rbbs(MSG *msg,FILE *infile)
{
struct message_header *head;
char temp[10];
int size,x;
fpos_t filepos;
head=(struct message_header *) e_malloc(sizeof(struct message_header));
fread(head,128,1,infile);
if(feof(infile))
return(-1);
if((head->active!=225 && head->active!=226) ||
head->date_sent[2]!='-' ||
head->date_sent[5]!='-')
failure("Error retrieving Message Header.\n");
if(head->private_flag=='*') msg->priv=TRUE;
else msg->priv=FALSE;
if(head->active==225) msg->active=TRUE;
else msg->active=FALSE;
termcpy(temp,head->msg_blk_size,4);
size=atoi(temp);
msg->size=size;
termcpy(msg->from,head->from,31);
termcpy(msg->to,head->to,22);
termcpy(msg->subject,head->subject,25);
termcpy(msg->password,head->password,15);
msg->level=head->read_sec_lev;
msg->conf=0;
termcpy(temp,head->msg_number,4);
msg->number=atoi(temp);
msg->read.hour=head->hour;
msg->read.minute=head->minute;
msg->read.second=head->second;
msg->read.month=head->month;
msg->read.day=head->day;
msg->read.year=head->year;
strncpy(temp,head->time_sent,8);
temp[2]='\0';
temp[5]='\0';
temp[8]='\0';
msg->sent.hour=atoi(temp);
msg->sent.minute=atoi(&temp[3]);
msg->sent.second=atoi(&temp[6]);
strncpy(temp,head->date_sent,8);
temp[2]='\0';
temp[5]='\0';
temp[8]='\0';
msg->sent.month=atoi(temp);
msg->sent.day=atoi(&temp[3]);
msg->sent.year=atoi(&temp[6]);
/********************************************************************
Skip multiple headers for Carbon Copy Function new to RBBS 17.4
NOTE: This is brute force technology at its finest. I tried to
use the Header_Number value, (which was always 32, SPACE, in earlier
versions of RBBS), but it really got out of hand. The docs for 17.4
suggest the following check for a REAL additional header, regardless
of the Header_number value. Which works a LOT better.
********************************************************************/
while(1)
{
fgetpos(infile,&filepos);
fread(head,128,1,infile);
if((head->active==225 || head->active==226) &&
head->date_sent[2]=='-' &&
head->date_sent[5]=='-')
{
size--;
continue;
}
fsetpos(infile,&filepos);
break;
}
msg->text_buffer=(char *)e_malloc(size*128);
memset(msg->text_buffer,' ',size*128);
size--;
for(x=0;x<size;x++)
{
fread(msg->text_buffer+(128*x),128,1,infile);
if(feof(infile)) return(-1);
}
free(head);
return(size);
}
/***************************************
Write a message to an RBBS message base
Returns the message number used.
***************************************/
int write_rbbs(MSG *msg,char *file)
{
FILE *outfile;
struct message_header *head;
CPR *cpr;
char temp[33];
int textblocks,x;
if ((outfile=fopen(file,"r+b"))==NULL)
{
printfwin(&warn,"\n----ERROR----\n");
printfwin(&warn,"Cannot open RBBS message file:\n \"%s\"\n",file);
exit(1);
}
head=(struct message_header *) e_malloc(sizeof(struct message_header));
cpr=(CPR *)e_malloc(sizeof(CPR));
read_rbbs_header(cpr,outfile);
cpr->last_msg_num++;
head->active=225;
/**************************************************************************
This line regards 17.4's multiple header value for "Carbon Copy" messages.
Unfortunately, it appears that older versions of RBBS will choke if this
value is anything but 32 (SPACE), even though the bytes is described as
"reserved". Since 17.4 will check for a valid header anyway, We can set
this to 32 and make both versions semi-happy.
**************************************************************************/
head->header_number=32;
head->read_sec_lev=msg->level;
if (msg->priv)
head->private_flag='*';
else
head->private_flag=' ';
padcpy(head->msg_number,ltoa(cpr->last_msg_num,temp,10),4);
msg->number=cpr->last_msg_num;
padcpy(head->from,msg->from,31);
padcpy(head->to,msg->to,22);
padcpy(head->subject,msg->subject,25);
padcpy(head->password,msg->password,15);
lpadcpy(head->msg_blk_size,ltoa(msg->size,temp,10),4);
sprintf(temp,"%d%d:%d%d:%d%d\n",
msg->sent.hour/10,
msg->sent.hour%10,
msg->sent.minute/10,
msg->sent.minute%10,
msg->sent.second/10,
msg->sent.second%10);
strncpy(head->time_sent,temp,8);
sprintf(temp,"%d%d-%d%d-%d%d\n",
msg->sent.month/10,
msg->sent.month%10,
msg->sent.day/10,
msg->sent.day%10,
msg->sent.year/10,
msg->sent.year%10);
strncpy(head->date_sent,temp,8);
head->month=msg->read.month;
head->day=msg->read.day;
head->year=msg->read.year;
head->hour=msg->read.hour;
head->minute=msg->read.minute;
head->second=msg->read.second;
putblock(head,cpr->next_msg_blk,outfile);
textblocks=msg->size-1;
for(x=0;x<textblocks;x++)
addblock(msg->text_buffer+(128*x),outfile);
cpr->last_msg_blk=cpr->next_msg_blk;
cpr->next_msg_blk+=msg->size;
write_rbbs_header(cpr,outfile);
free(cpr);
free(head);
fclose(outfile);
return(msg->number);
}
/********************************************************
Read in the Checkpoint Record block of the open file and
get some valuable info for the CPR struct.
********************************************************/
void read_rbbs_header(CPR *cpr, FILE *infile)
{
struct checkpoint_record *c_rec;
char temp[9];
c_rec=(struct checkpoint_record *) e_malloc(sizeof(struct checkpoint_record));
getblock(c_rec,0,infile);
termcpy(temp,c_rec->last_msg_num,8);
cpr->last_msg_num=atoi(temp);
termcpy(temp,c_rec->msg_start_blk,7);
cpr->first_msg_blk=atoi(temp)-1;
termcpy(temp,c_rec->last_msg_blk,7);
cpr->last_msg_blk=atoi(temp)-1;
termcpy(temp,c_rec->next_msg_blk,7);
cpr->next_msg_blk=atoi(temp)-1;
termcpy(temp,c_rec->msg_max,7);
cpr->msg_max=atoi(temp);
free(c_rec);
}
/*****************************************************
Write the modified data from the CPR structure to the
Checkpoint Record block of the open file.
*****************************************************/
void write_rbbs_header(CPR *cpr, FILE *infile)
{
struct checkpoint_record *c_rec;
char temp[33];
c_rec=(struct checkpoint_record *)e_malloc(sizeof(struct checkpoint_record));
getblock(c_rec,0,infile);
lpadcpy(c_rec->last_msg_num,ltoa(cpr->last_msg_num,temp,10),8);
lpadcpy(c_rec->next_msg_blk,ltoa(cpr->next_msg_blk+1,temp,10),7);
putblock(c_rec,0,infile);
free(c_rec);
}
/****************************************************************************
General code starts here
****************************************************************************/
void addtag(MSG *msg)
{
char *look,*end;
char tag[120];
strcpy(tag,"π [TOSS 1.2B] ");
strcat(tag,config.tagline);
strcat(tag,"π");
end=msg->text_buffer+128*(msg->size);
look=end;
while(*look!='π')
{
if(look < msg->text_buffer) return;
look--;
}
if((end-look)<207) msg->size++;
strncpy(look,tag,strlen(tag));
}
/**********************************************************
Dump a message to the display. This functions is not used,
but retained for in case I need to troubleshoot.
**********************************************************/
void show_msg(MSG *msg)
{
int x,c,size=msg->size-1;
printfwin(&proc,"\nMSG# %d\n",msg->number);
printfwin(&proc,"DATE: %d-%d-%d TIME: %d:%d:%d\n",
msg->sent.month,
msg->sent.day,
msg->sent.year,
msg->sent.hour,
msg->sent.minute,
msg->sent.second);
printfwin(&proc,"\nFROM: %s TO: %s\n",msg->from,msg->to);
printfwin(&proc,"SUBJECT: %s\n",msg->subject);
for(x=0;x<(size*128);x++)
{
c=(*(msg->text_buffer+x));
if(c=='π')
{
printfwin(&proc,"\n");
continue;
}
printfwin(&proc,"%c",c);
}
}
/***********************************************
Show the message header info in the PROC window
***********************************************/
void show_header(MSG *msg)
{
char cut[21];
printfwin(&proc," \nMessage: %d\n",msg->number);
termcpy(cut,msg->from,14);
printfwin(&proc," From: %s\n",cut);
termcpy(cut,msg->to,14);
printfwin(&proc," To: %s\n",cut);
termcpy(cut,msg->subject,14);
printfwin(&proc,"Subject: %s\n",cut);
}
/*******************************************************************
E_MALLOC() does the same as malloc, except error tests so we don't
have to all the time.
*******************************************************************/
void *e_malloc(size_t size)
{
void *pointer;
if ((pointer = (char *) malloc(size)) == NULL)
failure("Failure Allocating Free Memory");
return(pointer);
}
/**********************************************************
Here's a generic routine to retrieve a 128 byte block from
the specified, open file.
**********************************************************/
void getblock(void *buff,long block,FILE *infile)
{
fseek(infile,(long)block*128,SEEK_SET);
fread(buff,128,1,infile);
}
/*******************************************************
Here's a generic routine to write a 128 byte block from
memory to the specified, open file.
*******************************************************/
void putblock(void *buff,long block,FILE *outfile)
{
fseek(outfile,(long)block*128,SEEK_SET);
fwrite(buff,128,1,outfile);
}
/*******************************************************
Here's a generic routine to write a 128 byte block from
memory to the specified, open file at the current pos.
*******************************************************/
void addblock(void *buff,FILE *outfile)
{
fwrite(buff,128,1,outfile);
}
/***************************
Report an error to and exit
***************************/
void failure(char *str,...)
{
char buff[256];
va_list parms;
va_start(parms,str);
fcloseall();
vsprintf(buff,str,parms);
printwin(&warn,"--ERROR--\nProgram Terminating Because:\n ");
printwin(&warn,buff);
gotoxy(1,24);
exit(1);
}
/******************************************************
Copy (length) number of chars from one string to
another and pad with trailing spaces. Doesn't add NULL
******************************************************/
void padcpy(char *to, char *from,int length)
{
while(*from!=NULL && length>0)
{
*to=*from;
to++;
from++;
length--;
}
while(length>0)
{
*to=' ';
to++;
length--;
}
}
/******************************************
Same as padcpy(), buts add a leading space
******************************************/
void lpadcpy(char *to, char *from,int length)
{
*to=' ';
to++;
length--;
while(*from!=NULL && length>0)
{
*to=*from;
to++;
from++;
length--;
}
while(length>0)
{
*to=' ';
to++;
length--;
}
}
/*****************************************************
Copy (length) of one string to another and add a NULL
to the end. To read non-termed strings into C format.
*****************************************************/
void termcpy(char *to, char *from, int length)
{
while(length)
{
*to=*from;
to++;
from++;
length--;
}
*to='\0';
}
/********************************************
Fill in a dtg with the current date and time
********************************************/
void get_dtg(DTG *dtg)
{
struct tm *t;
time_t timer;
timer=time(NULL);
t=localtime(&timer);
dtg->hour=t->tm_hour;
dtg->minute=t->tm_min;
dtg->second=t->tm_sec;
dtg->month=t->tm_mon;
dtg->day=t->tm_mday;
dtg->year=t->tm_year;
}
/*************************************************
Remove leading whilespaces from the target string
*************************************************/
void remls(char *str)
{
char *ptr=str;
while(*ptr!='\0')
{
if(*ptr==' ' || *ptr=='\t')
strcpy(str,++ptr);
else
break;
}
}
/********************************************************
Copy (length) number of chars from one string to another
and pad with trailing spaces. And adds a NULL to the end
PLUS: Skips leading spaces or tabs.
********************************************************/
void padzcpy(char *to, char *from,int length)
{
while(*from==' ' || *from=='\t')
from++;
while(*from!=NULL && length>1)
{
*to=*from;
to++;
from++;
length--;
}
while(length>1)
{
*to=' ';
to++;
length--;
}
*to='\0';
}
/****************************************************
Read in one line from a text file, returns -1 on EOF
I use this because fgets() and fscanf() work lousy
****************************************************/
int instr(char *targ, FILE *infile)
{
int c;
while(!feof(infile))
{
c=getc(infile);
*targ=c;
if(c=='\n')
{
*targ='\0';
return(0);
}
targ++;
}
return(-1);
}
/********************************************
Direct screen writing text windows routines.
Very primitive, but fast and easy, which is
nothing to sneeze at.
********************************************/
void printfwin(WIN *win, char *str,...)
{
char buff[256];
va_list parms;
va_start(parms,str);
vsprintf(buff,str,parms);
printwin(win,buff);
}
void printwin(WIN *win, char *str)
{
while(*str!='\0')
{
if(win->cx>=win->x2)
{
win->cx=win->x1+1;
win->cy++;
}
if(win->cy >= win->y2)
scrollwin(win);
if(*str=='\b')
{
if(win->cx>1)
win->cx--;
str++;
continue;
}
if(*str=='\n')
{
win->cx=win->x1+1;
win->cy++;
str++;
continue;
}
*(win->screen+(win->cx++)+(win->cy*80))=*(str++)|win->text<<8;
}
}
void scrollwin(WIN *win)
{
int x,y;
win->cx=win->x1+1;
win->cy=win->y2-1;
y=win->y1+1;
while(y<(win->y2-1))
{
y++;
for(x=win->x1+1;x<(win->x2);x++)
*(win->screen+x+((y-1)*80))=*(win->screen+x+(y*80));
}
for(x=win->x1+1;x<(win->x2);x++)
*(win->screen+x+(y*80))=32|win->text<<8;
}
void openwin(WIN *win)
{
struct text_info tinfo;
int x,y,h,s;
gettextinfo(&tinfo);
if(tinfo.currmode==MONO)
{
win->screen=(int far *)0xB0000000;
win->border=7;
win->text=15;
win->header=15;
}
else
win->screen=(int far *)0xB8000000;
win->cx=win->x1+1;
win->cy=win->y1+1;
x=win->x1;
y=win->y1;
h=win->y2-y;
*(win->screen+x+(y*80))=201|win->border<<8;
*(win->screen+(++x)+(y*80))=181|win->border<<8;
for(s=0;s<strlen(win->title);s++)
*(win->screen+(++x)+(y*80))=*(win->title+s)|win->header<<8;
*(win->screen+(++x)+(y*80))=198|win->border<<8;
while(x<(win->x2-1))
*(win->screen+(++x)+(y*80))=205|win->border<<8;
*(win->screen+(++x)+(y*80))=187|win->border<<8;
while(--h)
{
x=win->x1;
*(win->screen+x+(++y*80))=186|win->border<<8;
while(x<(win->x2-1))
*(win->screen+(++x)+(y*80))=32|win->text<<8;
*(win->screen+(++x)+(y*80))=186|win->border<<8;
*(win->screen+(++x)+(y*80))&=0xfff;
}
x=win->x1;
y++;
*(win->screen+x+(y*80))=200|win->border<<8;
while(x<(win->x2-1))
*(win->screen+(++x)+(y*80))=205|win->border<<8;
*(win->screen+(++x)+(y*80))=188|win->border<<8;
*(win->screen+(++x)+(y*80))&=0xfff;
x=win->x1+1;
y++;
while(x<(win->x2+1))
*(win->screen+(++x)+(y*80))&=0xfff;
}
void wallpaper(WIN *win)
{
struct text_info tinfo;
int x,s;
gettextinfo(&tinfo);
if(tinfo.currmode==MONO)
{
win->screen=(int far *)0xB0000000;
win->border=7;
win->text=15;
win->header=15;
}
else
win->screen=(int far *)0xB8000000;
for(x=0,s=0;s<strlen(win->title);s++)
*(win->screen+(x++))=*(win->title+s)|win->header<<8;
while(x<80)
*(win->screen+(x++))=32|win->header<<8;
for(x=80;x<1920;x++)
*(win->screen+x)=176|win->border<<8;
}